#include "applycertificateModule.h"
#include <QDebug>
#include "utils/config.h"
#include "utils/eccoperator.h"
#include <utils/keymanager.h>

applyCertificateModule::applyCertificateModule()
    : ModuleInterface()
{}

/**
 * @brief applyCertificateModule::initialize  这个函数是用来初始化参数的
 * 我们需要先生成CSR和私钥的
 */
bool applyCertificateModule::initialize()
{
    //然后这里就是提取CA的公钥了
    EVP_PKEY *CA_public = nullptr;
    EVP_CA_pubKey.reset(CA_public, EVP_PKEY_Deleter);
    if (!CertificateManager::instance().loadCACertificate(&CA_public, CA_CERT_FILEPATH)) {
        qDebug() << "CA cert is error!";
        return false;
    }

    BN_priKey = m_ecc.GeneratePriKey();
    ECPOINT_pubKey = m_ecc.GeneratePubKey(BN_priKey.get());
    //然后就是将这两个密钥对转换为EVP_PKEY类型
    EVP_PKEY *keyPair = nullptr;
    int result = m_ecc.BN_ECKey_Conv_EC_EVPKey(BN_priKey.get(),
                                               ECPOINT_pubKey.get(),
                                               m_ecc.getGroup(),
                                               &keyPair);
    if (!result) {
        std::cerr << "BN_ECKey_Conv_EC_EVPKey is error!" << std::endl;
        return false;
    }
    EVP_pairKey.reset(keyPair, EVP_PKEY_Deleter);
    //同时需要保存私钥
    if (!certManger.savePrivateKey(keyPair, CLIENT_PRIKEY_FILEPATH)) {
        return false;
    }

    EVP_PKEY *evp_priKey = nullptr;
    if (!m_ecc.BN_Convert_EVPPriKey(BN_priKey.get(), m_ecc.getGroup(), &evp_priKey)) {
        std::cerr << "BN_Convert_EVPPriKey is error!" << std::endl;
        return false;
    }

    EVP_priKey.reset(evp_priKey, EVP_PKEY_Deleter);

    EVP_PKEY *evp_pubKey = nullptr;
    if (!m_ecc.ECPubKey_Conv_EVPPubKey(ECPOINT_pubKey.get(), m_ecc.getGroup(), &evp_pubKey)) {
        std::cerr << "ECPubKey_Conv_EVPPubKey is error!" << std::endl;
        return false;
    }

    EVP_pubKey.reset(evp_pubKey, EVP_PKEY_Deleter);
    return true;
}

QByteArray applyCertificateModule::execute()
{
    //这里就是需要生成CSR了

    X509_REQ *cert_csr = CertManger.generateCSR(subjectInfo, EVP_pairKey.get());
    if (!cert_csr) {
        std::cerr << "generateCSR is failed!" << std::endl;
        return {};
    }

    std::vector<unsigned char> der_data;
    if (!CertManger.X509_REQ_to_DER(cert_csr, der_data)) {
        std::cerr << "Failed to execute X509_REQ_to_DER" << std::endl;
        X509_REQ_free(cert_csr);
        return {};
    }

    QByteArray byteArray(reinterpret_cast<const char *>(der_data.data()), der_data.size());
    X509_REQ_free(cert_csr);
    return byteArray;
}

bool applyCertificateModule::handleReceiveData(const QByteArray &receiveData)
{
    //然后需要将data转换为string
    std::string certdata_str = receiveData.toStdString();

    //这个发送的数据是der格式的，因此需要将DER格式转换为X509 然后再保存起来
    X509 *cert = certManger.convertDERToX509(reinterpret_cast<const unsigned char *>(
                                                 certdata_str.c_str()),
                                             certdata_str.size());
    if (!cert) {
        std::cerr << "Failed to convertDERToX509!" << std::endl;
        return false;
    }

    //然后需要保存证书
    if (!certManger.saveCertificate(cert, CLIENT_CERT_FILEPATH)) {
        std::cerr << "Failed to saveCertificate!" << std::endl;
        return false;
    }

    //将私钥和公钥都转换为EVP_PKEY形式的

    //这里保存好了的，因此需要将密钥传递给密钥管理类
    keyManager::instance().setKeys(BN_priKey, ECPOINT_pubKey, EVP_priKey, EVP_pubKey);

    return true;
}
